package com.qf.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.event.util.EventUtil;
import com.qf.aop.UserLocal;
import com.qf.coupon.CouponUtil;
import com.qf.coupon.limit.ILimit;
import com.qf.coupon.rule.IRule;
import com.qf.dao.OrdersDao;
import com.qf.entity.*;
import com.qf.feign.CouponFeign;
import com.qf.feign.HotalFeign;
import com.qf.service.IOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Service
public class OrderServiceImpl extends ServiceImpl<OrdersDao, Orders> implements IOrderService {

    @Autowired
    private HotalFeign hotalFeign;

    @Autowired
    private EventUtil eventUtil;

    @Autowired
    private CouponFeign couponFeign;

    /**
     * 计算订单的总价格以及价格明细
     * @param pricesParams
     * @return
     */
    @Override
    public PricesResult getPrices(PricesParams pricesParams) {

        //根据房间id 查询房间信息
        R<Room> roomResult = hotalFeign.getRoomById(pricesParams.getRid());
        Room room = roomResult.getData();

        //获得房间的日期价格列表
        List<RoomPrice> prices = room.getPrices();

        //总价的汇总对象
        BigDecimal allPrice = BigDecimal.valueOf(0);

        //价格的明细
        // 2020-10-01  2 x 199
        // 2020-10-02  2 x 299
        // 2020-10-03  2 x 99
        List<List<String>> priceDetils = new ArrayList<>();

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");

        //循环价格列表
        for (int i = 0; i < prices.size(); i++) {
            //日期的过滤
            if (prices.get(i).getDate().getTime() >= pricesParams.getBeginTime().getTime()
                    && prices.get(i).getDate().getTime() < pricesParams.getEndTime().getTime()) {

                //这一天房间数量是否足够
                if(prices.get(i).getHasNumber() - prices.get(i).getNumber() < pricesParams.getRnumber()){
                    //说明房间不足
                    return new PricesResult().setCode(1);
                }

                //获得房间当前价格 = 单价 * 房间数量
                BigDecimal priceDay = BigDecimal.valueOf(prices.get(i).getPrice()).multiply(BigDecimal.valueOf(pricesParams.getRnumber()));

                //计算总价
                allPrice = allPrice.add(priceDay);

                //计算当前的价格明细
                List<String> list = new ArrayList<>();
                list.add(simpleDateFormat.format(prices.get(i).getDate()));
                list.add(pricesParams.getRnumber() + " X " + prices.get(i).getPrice());
                priceDetils.add(list);
            }
        }

        //判断是否使用了优惠券
        if (pricesParams.getCid() != null && pricesParams.getCid() > -1) {

            //查询优惠券信息
            Coupon coupon = couponFeign.queryById(pricesParams.getCid()).getData();

            //优惠券规则
            IRule rule = CouponUtil.parseDynamicRuleField(coupon);
            //优惠券的限制
            ILimit limit = CouponUtil.parseDynamicLimitField(coupon);

            if (limit == null || limit.isUsing(pricesParams)) {
                //说明当前优惠券可用
                if(rule.canUser(allPrice.doubleValue())){
                    //进行优惠
                    BigDecimal oldPirce = allPrice;
                    allPrice = BigDecimal.valueOf(rule.youhui(allPrice.doubleValue()));

                    //记录优惠的明细
                    List<String> list = new ArrayList<>();
                    list.add("使用了优惠券");
                    list.add(" - " + oldPirce.subtract(allPrice).doubleValue());
                    priceDetils.add(list);
                }
            }
        }

        //构建返回值
        PricesResult result = new PricesResult()
                .setAllPrice(allPrice.doubleValue())
                .setPriceDetails(priceDetils);

        return result;
    }

    /**
     * 生成订单的方法
     * @param orders
     * @param pricesParams
     * @return
     */
    @Override
    @Transactional
    public String createOrders(Orders orders, PricesParams pricesParams) {

        //获得当前用户
        User user = UserLocal.getUser();

        //计算总价
        PricesResult prices = this.getPrices(pricesParams);

        //计算入住的天数
        int days = (int) ((orders.getEndTime().getTime() - orders.getBeginTime().getTime()) / 1000 / 60 / 60 / 24);

        //生成订单号
        //生成规则 UUID
        //yyMMdd + 4位的用户id + redis的递增序列    set number 1    incr number
        String oid = UUID.randomUUID().toString();

        //设置订单的属性
        orders
                .setOid(oid)
                .setUid(user.getId())
                .setNumber(pricesParams.getRnumber())
                .setAllPrice(prices.getAllPrice())
                .setDays(days);

        //保存订单
        super.save(orders);

        //修改数据库房间的预订数量、ES中的预订数量
        eventUtil.publishEvent("create_orders", pricesParams);

        return oid;
    }
}
